﻿using PdfSharp.Drawing;
using PdfSharp.Pdf;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace dzjc
{

    public partial class Form1 : Form
    {
        readonly string Title = "中小学电子教材 v1.4";

        //页数
        int PageCount { get; set; } = 1;
        int _pageIndex = 1;
        int PageIndex
        {
            get { return _pageIndex; }
            set
            {
                if (value > PageCount) _pageIndex = PageCount;
                if (value > 0 && value <= PageCount) _pageIndex = value;
            }
        }
        //数据
        Details _details;

        //正在下载标志
        volatile bool _loading = false;
        //下载文件夹
        string _saveFilePath = null;


        public Form1()
        {
            InitializeComponent();
            Application.ThreadException += (o, e) => statusLabel1.Text = e.Exception.Message;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Text = Title;
            label1.Text = "0";
            button1.Text = "首页";
            button2.Text = "上一页";
            button3.Text = "下一页";
            button4.Text = "尾页";
            statusLabel1.Text = "https://www.zxx.edu.cn/tchMaterial";
            tableLayoutPanel1.Enabled = false;

            //右键菜单
            var contextMenu = new ContextMenuStrip();
            contextMenu.Items.Add("保存图片").Click += (o, ea) => ImageSave();
            contextMenu.Items.Add("图片转PDF").Click += (o, ea) => DownJpgToPdfFile();
            contextMenu.Items.Add("打印（建议选PDF打印机）").Click += (o, ea) => DownJpgToPrint();
          
            pictureBox1.ContextMenuStrip = contextMenu;
        }


        private void Form1_Shown(object sender, EventArgs e)
        {
            SetTreeView1();
            statusLabel1.Text = "节点单击浏览，双击下载。";
        }

        //资源树
        void SetTreeView1()
        {
            //数据整理
            var dataList = WebData.Get();
            var pathDict = new Dictionary<string, string>();
            foreach (var data in dataList)
            {
                if (data.tag_list == null) continue;
                data.tag_list.ForEach(d => pathDict[d.tag_id] = d.tag_name);
                var paths = data.tag_paths.FirstOrDefault();
                if (paths == null) continue;

                var nodes = treeView1.Nodes;
                var pathArr = paths.Split('/');
                foreach (var path in pathArr)
                {
                    pathDict.TryGetValue(path, out string txt);
                    txt = txt ?? "教材";
                    if (nodes.ContainsKey(txt))
                    {
                        nodes = nodes[txt].Nodes;
                    }
                    else
                    {
                        var node = nodes.Add(txt, txt);
                        nodes = node.Nodes;
                        if (path == pathArr.Last()) node.Tag = data.id;
                    }
                }
            }

            //展开节点
            treeView1.Nodes?[0].Expand();
            treeView1.Nodes?[0].Nodes?[0].Expand();

            //单击事件
            treeView1.NodeMouseClick += (sender, args) =>
               {
                   var node = args.Node;
                   if (node.Tag is string id)
                   {
                       _details = WebData.GetDetails(id);
                       PageCount = _details.Page;
                       trackBar1.Maximum = PageCount;
                       SetPage(1);
                       tableLayoutPanel1.Enabled = true;
                       statusLabel1.Text = _details.Title;
                   }
               };

            //双击事件
            treeView1.NodeMouseDoubleClick += async (sender, args) =>
            {
                //是否下载中
                if (_loading) return;
                _loading = true;

                //5级节点以上
                var node = args.Node;
                if (node.FullPath.Split('\\').Length >= 6)
                {
                    var nodeList = new List<TreeNode>();
                    GetNodesIndex(node, ref nodeList);
                    if (SetFilePath())
                    {
                        foreach (var item in nodeList)
                        {
                            if (item.Tag is string id)
                            {
                                try
                                {
                                    var name = $"{string.Join("-", item.FullPath.Split('\\').Skip(1))}.pdf";
                                    await DownFileAsync(_details.Pdf, name);
                                }
                                catch (Exception ex)
                                {
                                    statusLabel1.Text = ex.Message;
                                }
                            }
                        }
                    }
                }
                _loading = false;
            };

            void GetNodesIndex(TreeNode node, ref List<TreeNode> iList)
            {
                iList.Add(node);
                foreach (TreeNode item in node.Nodes)
                {
                    GetNodesIndex(item, ref iList);
                }
            }

            //按钮事件            
            button1.Click += (sender, args) => SetPage(1);
            button2.Click += (sender, args) => SetPage(--PageIndex);
            button3.Click += (sender, args) => SetPage(++PageIndex);
            button4.Click += (sender, args) => SetPage(int.MaxValue);
            trackBar1.ValueChanged += (sender, args) => SetPage(trackBar1.Value);

        }

        byte[] DownJpg(int p)
        {
            var url = Regex.Replace(_details.Jpg, "\\d+.jpg", $"{p}.jpg");
            var bytes = new WebClient().DownloadData(url);
            return bytes;
        }

        void SetPictureBox()
        {
            var url = _details.Jpg;
            pictureBox1.Visible = PageCount > 0;
            if (!string.IsNullOrWhiteSpace(url))
            {
                byte[] bytes = DownJpg(PageIndex);
                using (var ms = new MemoryStream(bytes))
                {
                    pictureBox1.Image = Image.FromStream(ms);
                }
                GC.Collect();
            }
        }

        void SetPage(int p)
        {
            tableLayoutPanel1.Enabled = false;
            PageIndex = p;
            SetPictureBox();
            trackBar1.Value = PageIndex;
            label1.Text = $"{PageIndex}/{PageCount}";
            tableLayoutPanel1.Enabled = true;
        }

        bool SetFilePath()
        {
            if (_saveFilePath == null)
            {
                var dialog = new FolderBrowserDialog();
                if (dialog.ShowDialog() == DialogResult.OK) _saveFilePath = dialog.SelectedPath;
            }
            return _saveFilePath != null;
        }

        //替换非法字符 
        string ReplaceInvalidChars(string name)
        {
            var result = name;
            Path.GetInvalidFileNameChars().ToList().ForEach(x => result = result.Replace(x, '_'));
            return result;
        }

        //下载文件
        async Task DownFileAsync(string url, string name)
        {
            statusLabel1.Text = name;
            var path = Path.Combine(_saveFilePath, ReplaceInvalidChars(name));
            if (!File.Exists(path))
            {
                var web = new WebClient();
                web.DownloadProgressChanged += (o, e) => progressBar1.Value = e.ProgressPercentage;
                await web.DownloadFileTaskAsync(url, path);
                statusLabel1.Text = "完成！";
            }
            else
            {
                statusLabel1.Text = "文件已存在！";
            }
        }

        // 图片转PDF
        void DownJpgToPdfFile()
        {
            if (_details == null) return;
            var dialog = new SaveFileDialog()
            {
                Filter = "PDF文件|*.PDF",
                FileName = ReplaceInvalidChars(_details.Title) + ".pdf"
            };
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                using (var doc = new PdfDocument())
                {
                    for (int i = 1; i <= PageCount; i++)
                    {
                        progressBar1.Value = i;
                        var page = doc.AddPage();
                        using (var gfx = XGraphics.FromPdfPage(page))
                        {
                            var bytes = DownJpg(i);
                            using (var ms = new MemoryStream(bytes))
                            {
                                using (var img = XImage.FromStream(ms))
                                {
                                    gfx.DrawImage(img, 2, 2, page.Width - 5, page.Height - 5);
                                }
                            }
                        }
                    }
                    doc.Save(dialog.FileName);
                }
                GC.Collect();
            }
        }

        //打印页计数
        int iPrintPage = 1;
        //打印图片文件
        void DownJpgToPrint()
        {
            if (_details == null) return;
            iPrintPage = 1;
            var doc = new PrintDocument { DocumentName = ReplaceInvalidChars(_details.Title) };
            doc.PrintPage += (object sender, PrintPageEventArgs e) =>
            {
                var gfx = e.Graphics;
                var bytes = DownJpg(iPrintPage++); //不能使用异步方法
                using (var ms = new MemoryStream(bytes))
                {
                    using (var img = Image.FromStream(ms))
                    {
                        gfx.DrawImage(img, e.PageBounds);
                    }
                }
                if (iPrintPage <= PageCount) e.HasMorePages = true;
            };
            var dialog = new PrintDialog { Document = doc };
            if (dialog.ShowDialog() == DialogResult.OK) doc.Print();
            GC.Collect();
        }

        //保存图片
        private void ImageSave()
        {
            if (pictureBox1.Image != null)
            {
                var dialog = new SaveFileDialog() { Filter = "图片文件(*.JPG)|*.JPG", FileName = $"{PageIndex}" };
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    new Bitmap(pictureBox1.Image).Save(dialog.FileName, ImageFormat.Jpeg);
                }
            }
        }


        private void toolStripStatusLabel2_Click(object sender, EventArgs e)
        {
            var url = "https://gitee.com/zhux3/dzjc";
            Help.ShowHelp(this, url);
        }


    }
}
